// import { transformFromAstAsync } from '@babel/core'
// import { transformFromAst } from '@babel/standalone'
import { transformFromAstAsync, traverse, type NodePath, types as t  } from '@babel/core'
import { babel_transformFromAstAsync } from "./jsx"

export function parseTraverseAst(fileAst:any) {
  const depsList : string[] = [];
  let hasJsx = false;
  let hasTsx = false;
  traverse(fileAst, {
    ExportAllDeclaration(path: any) {
      depsList.push(path.node.source.value);
    },
    ImportDeclaration(path:any) {
      depsList.push(path.node.source.value);
    },
    CallExpression(path:any) {
      if (
        // @ts-ignore (Property 'name' does not exist on type 'ArrayExpression')
        path.node.callee.name === 'require'
        && path.node.arguments.length === 1
        && t.isStringLiteral(path.node.arguments[0])
      ) {
        depsList.push(path.node.arguments[0].value)
      }
    },
    // 检查 JSXElement 和 JSXFragment 节点以判断是否为 JSX
    JSXElement(path) {
      hasJsx = true;
    },
    JSXFragment(path) {
      hasJsx = true;
    },
    // 检查 TypeScript 特定的节点类型以判断是否为 TSX
    TSTypeAnnotation(path) {
      hasTsx = true;
    },
    TSInterfaceDeclaration(path) {
      hasTsx = true;
    },
    TSPropertySignature(path) {
      hasTsx = true;
    },
  });

  return {
    depsList,
    hasJsx,
    hasTsx
  };
}


/**
 * import is a reserved keyword, then rename
 * @internal
 */
export function renameDynamicImport(fileAst : t.File) : void {
  traverse(fileAst, {
    CallExpression(path : NodePath<t.CallExpression>) {
      if ( t.isImport(path.node.callee) )
        path.replaceWith(t.callExpression(t.identifier('__vsfcl_import__'), path.node.arguments))
    }
  });
}

export async function transformAst(ast: any, source: string, moduleSourceType: boolean, additionalBabelPlugins: any = {}, devMode: boolean, log: any){
  renameDynamicImport(ast);
  const { depsList, hasJsx, hasTsx } = parseTraverseAst(ast);
  let code = source
  if (hasJsx||hasTsx){
    const result: any = await babel_transformFromAstAsync(ast, source, moduleSourceType, additionalBabelPlugins,devMode)
    code = result.code
  }
  return {
    depsList,
    hasJsx,
    hasTsx,
    code
  }
}